package cn.reyuxi.simple

import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.contains
import cn.reyuxi.emptyview.VisibilityHandler

class SimpleVisibilityHandler : VisibilityHandler {
    private var contentParent: ViewGroup? = null
    private var emptyView: View? = null
    private var contentView: View? = null
    private var contentViewIndex: Int = -1


    override fun onShow(emptyView: View, contentView: View) {
        contentParent = contentView.parent as ViewGroup
        this.emptyView = emptyView
        this.contentView = contentView
        for (i in 0 until (contentParent!!.childCount)) {
            if (contentParent!!.getChildAt(i) === contentView) {
                contentViewIndex = i
                break
            }
        }
        handleShowHide(true)
    }

    override fun onHide() {
        handleShowHide(false)

        this.contentView = null
        this.emptyView = null
        this.contentParent = null
    }

    private fun handleShowHide(isShow: Boolean) {
        if (contentView == null || emptyView == null || contentParent == null) return
        when (val p = contentParent!!) {
            is FrameLayout -> handleForFrameLayout(p, isShow)

            is ConstraintLayout -> handleForConstraintLayout(p, isShow)

            is LinearLayout -> handleForLinearLayout(p, isShow)
        }

        if (!isShow) contentViewIndex = -1
    }


    private fun handleForFrameLayout(p: FrameLayout, isShow: Boolean) {
        emptyView!!.run {
            this.layoutParams = FrameLayout.LayoutParams(contentView!!.layoutParams)

            if (isShow) {
                p.addView(this, contentViewIndex)
                return@run
            }

            if (p.contains(this)) {
                p.removeView(this)
            }
        }
    }

    private fun handleForConstraintLayout(p: ConstraintLayout, isShow: Boolean) {
        emptyView!!.apply {
            if (id == View.NO_ID) {
                id = View.generateViewId()
            }
        }.also { emptyView ->
            val contentIndex = contentViewIndex
            if (isShow) {
                contentView!!.visibility = View.INVISIBLE
                p.addView(emptyView, contentIndex, ConstraintLayout.LayoutParams(0, 0))
                p.bringChildToFront(emptyView)
                ConstraintSet().also {
                    it.clone(p)
                }.run {
                    connect(
                        emptyView.id,
                        ConstraintSet.START,
                        contentView!!.id,
                        ConstraintSet.START
                    )
                    connect(emptyView.id, ConstraintSet.TOP, contentView!!.id, ConstraintSet.TOP)
                    connect(emptyView.id, ConstraintSet.END, contentView!!.id, ConstraintSet.END)
                    connect(
                        emptyView.id,
                        ConstraintSet.BOTTOM,
                        contentView!!.id,
                        ConstraintSet.BOTTOM
                    )
                    applyTo(p)
                }
                return@also
            }

            if (p.contains(emptyView)) {
                p.removeView(emptyView)
                contentView!!.visibility = View.VISIBLE
            }
        }
    }

    private fun handleForLinearLayout(p: LinearLayout, isShow: Boolean) {
        val contentIndex = contentViewIndex
        if (isShow) {
            emptyView!!.run {
                layoutParams = LinearLayout.LayoutParams(contentView!!.layoutParams)
            }
            if (contentIndex >= 0) {
                p.removeViewAt(contentIndex)
                p.addView(emptyView, contentIndex)
            }
            return
        }
        if (contentIndex >= 0 && p.contains(emptyView!!)) {
            p.removeView(emptyView)
            p.addView(contentView!!, contentIndex)
        }
    }
}